import uuid
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from django.conf import settings
from datetime import timedelta, datetime

from . import models
from libs.alipay_sdk import alipay, alipay_gateway


class OrderModelSeriailzer(serializers.ModelSerializer):
    member = serializers.PrimaryKeyRelatedField(write_only=True, queryset=models.Member.objects.all())

    class Meta:
        model = models.Order
        fields = ['total_amount', 'subject', 'pay_type', 'member', 'order_detail_list']
        extra_kwargs = {
            'total_amount': {'required': True},
            'pay_type': {'required': True},
            'order_detail_list': {'read_only': True},
        }

    @staticmethod
    def _verify_amount(attrs):
        total_amount = attrs.get('total_amount')
        member = attrs.get('member')
        if member.price == total_amount:
            return total_amount
        raise ValidationError("订单总价错误!")

    @staticmethod
    def _order_number():
        return str(uuid.uuid1()).replace('-', '')

    def _pay_user(self):
        return self.context['request'].user

    def _pay_link(self, out_trade_no, total_amount, subject):
        # print('total_amount:', total_amount, type(total_amount))  # total_amount: 138.00 <class 'decimal.Decimal'>
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=out_trade_no,  # 订单号, 必须唯一
            # 支付宝支付的时候pay_total_amount是一个decimal类型, 需要转换成float类型. (提示: decimal累加可以)
            # 如果不转换成float那么格式就会抛出异常:  Object of type 'Decimal' is not JSON serializable
            # total_amount=total_amount,       # 总金额
            total_amount=float(total_amount),  # 总金额
            subject=subject,  # 订单标题
            return_url=settings.NOTIFY_URL,  # 同步回调(支付成功)
            notify_url=settings.NOTIFY_URL  # 异步回调(订单状态) 可选, 不填则使用默认notify url
        )
        return alipay_gateway + order_string

    def _before_create(self, attrs, out_trade_no, user, pay_link):
        attrs['out_trade_no'] = out_trade_no
        attrs['user'] = user

        self.context['pay_link'] = pay_link

    def create(self, validated_data):
        member = validated_data.pop('member')
        order = models.Order.objects.create(**validated_data)
        models.OrderDetail.objects.create(member=member, order=order, price=member.price, real_price=member.price)
        return order

    def validate(self, attrs):
        # 1. 校验订单总价格
        total_amount = self._verify_amount(attrs)
        # 2. 生成订单号
        order_number = self._order_number()
        # 3. 获取支付用户
        user = self._pay_user()
        # 4. 生成支付连接
        pay_link = self._pay_link(out_trade_no=order_number, total_amount=total_amount, subject=attrs.get('subject'))
        # 5. 入库(订单, 订单详情)
        self._before_create(attrs=attrs, out_trade_no=order_number, user=user, pay_link=pay_link)
        return attrs
